

package cuttings;

import java.net.*;
import java.util.* ;
import java.lang.Object.*;
import java.io.*;


public class UserRole
{
     static Vector<String> MyParticipants = new Vector<String>();
     static Vector<String> MyAttackers = new Vector<String>();
     static Vector<String> MyDefenders = new Vector<String>();

     //static Vector<MyGame> gameObjects = new Vector<MyGame>();
     static Hashtable hoststable = new Hashtable(); //host username to game id populated by server
     static Hashtable usertoobj = new Hashtable();
     static Hashtable hoststatushash = new Hashtable();

     static int myScore = 0;
     static int teamScore = 0;
     static int opponentScore = 0;
     static int winningScore = 49;

     static Hashtable usersScore = new Hashtable(); //maintained by server (uname:score)
     static Hashtable usersAttackerScore = new Hashtable();
     static Hashtable usersDefenderScore = new Hashtable();

     static Hashtable<String,Integer> attackersScoreHash = new Hashtable<String,Integer>();
     static Hashtable<String,Integer> defendersScoreHash = new Hashtable<String,Integer>();

     static int attackersScore = 0;
     static int defendersScore = 0;

     final String CRLF = "\r\n";
     static String fileName = "467.pdf";
     static int milestonereached = 0;


     public static void userLogin(String userName,String password) throws Exception
     {
        System.out.println("in userLogin");
        ServerConnect.sendToServer("login "+userName+","+password);
     }

     static public void createNewUser(String userName,String passWord,String email) throws Exception
     {
         ServerConnect.sendToServer("newuser "+userName+","+passWord+","+email);
         //call newUserStatus(1) if successful
     }

     static public void userLogout(String userName, int sendToPeers) throws Exception
     {
         if(sendToPeers==1)
         {
            SendSocketsList.sendToAll("#:userLogout:"+userName);
            System.exit(0);
         }
     }

     static public String createNewGame(String hostName) throws Exception
     {
         //if(!TCPClient.MyGameHostName.equals("NULL"))
         {

            int gameID = hostName.hashCode();
            TCPClient.MyGameHostName = hostName;
            TCPClient.MyGameID = Integer.toString(gameID);

            System.out.println("NewGame: "+TCPClient.name+","+TCPClient.MyGameHostName+","+TCPClient.MyGameID);

         //let server know you are hosting a new game
            ServerConnect.sendToServer("host "+hostName+","+gameID);
         //i am a participant
            MyParticipants.add(TCPClient.name);
         }

         return TCPClient.MyGameID;
     }

     static public void constructHostList(String messageFromServer)
     {
         String hosts[] = messageFromServer.split(";");

         for (int i=0;i<hosts.length;i++)
         {
            String temp[] = hosts[i].split(",");
            if(temp[0].equals("addhost"))
            {
                hoststable.put(temp[1],temp[2]);
                hoststatushash.put(temp[1],temp[3]);
                System.out.println("Addedhost: "+temp[1]);
            }
            else
            {
                if(hoststable.containsKey(temp[1]))
                {
                    hoststable.remove(temp[1]);
                    hoststatushash.remove(temp[1]);
                }
            }
         }

         getHostList();
     }

     //static public String[][] getHostList()
     static public void getHostList()
     {
         int no_of_hosts = hoststable.size();
         String hostList[][] = new String[no_of_hosts][2];

         Enumeration keys = hoststable.keys();


         int i=0;
         String hostName;
         Object temp;

         while(keys.hasMoreElements())
         {
             temp = keys.nextElement();
             hostName = temp.toString();

             hostList[i][0] = hostName;
             hostList[i][1] = (String)hoststable.get(hostName);
             i++;
         }

         Menu.updateServerList(hostList);
         //return hostList;
 
     }

     //send invitation to a particular user - initiated by a host
     static public void sendInvite(String userName) throws Exception
     {
         System.out.println("in sendinvite");
         if(hoststable.containsKey(TCPClient.name))
         {
             System.out.println("entered sendinvite");
             String tempID = (String)hoststable.get(TCPClient.name);
             SendSocketsList.sendToPeer(userName,"#:popupInvite:"+tempID+":");
         }
     }

     static public void acceptInvitation(String hostName,String userName,String gameID) throws Exception
     {
         TCPClient.MyGameHostName = hostName;
         TCPClient.MyGameID = gameID;

         //inform my host that I have joined his game; he needs to populate my vector lists.
         SendSocketsList.sendToPeer(hostName,"#:joinedGame:"+userName+":");
     }

     //called if I am host and some user joined my game
     static public void joinedGame(String userName) throws Exception
     {
         System.out.println("in joined game");
         if(hoststable.containsKey(TCPClient.name))
         {
             System.out.println("entered joined game");
             MyParticipants.add(userName);
             String participantList = "#:populateParticipants:";
             for(int i=0;i<MyParticipants.size();i++)
                 participantList += MyParticipants.get(i)+",";
             participantList = participantList.substring(0,participantList.length()-1); //remove last comma
             participantList += ":";

             sendToParticipants(participantList);
             //initialize attackers and defenders list
             if(MyAttackers.size()>0)
                pushAttackersList(userName);
             if(MyDefenders.size()>0)
                 pushDefendersList(userName);
         }
     }

     static public void quitGame(String userName,int sendToPeers) throws Exception
     {
         removeParticipant(userName);
         removeAttackerList(userName);
         removeDefenderList(userName);

         if(sendToPeers==1)
         {
             TCPClient.MyGameHostName = "NULL";
             TCPClient.MyGameID = "NULL";
             sendToParticipants("#:quitGame:"+userName+":0:");
         }
     }

     static public void addParticipant(String userName)
     {
         if(!MyParticipants.contains(userName))
            MyParticipants.add(userName);
     }

     static public void addAttackerList(String userName)
     {
         if(!MyAttackers.contains(userName))
            MyAttackers.add(userName);
     }

     static public void addDefenderList(String userName)
     {
         if(!MyDefenders.contains(userName))
            MyDefenders.add(userName);
     }

     static public void removeParticipant(String userName)
     {
            MyParticipants.remove(userName);
     }

     static public void removeAttackerList(String userName)
     {
            MyAttackers.remove(userName);
     }

     static public void removeDefenderList(String userName)
     {
            MyDefenders.remove(userName);
     }

     static public void sendToParticipants(String message) throws Exception
     {
         System.out.println("Sending to participants: "+message);
         for(int i=0;i<MyParticipants.size();i++)
         {
             if(!MyParticipants.get(i).equals(TCPClient.name));
             SendSocketsList.sendToPeer(MyParticipants.get(i),message);
         }
     }

     static public void sendToAttackers(String message) throws Exception
     {
         System.out.println("Sending to attackers: "+message);
         for(int i=0;i<MyAttackers.size();i++)
         {
             if(!MyAttackers.get(i).equals(TCPClient.name));
             SendSocketsList.sendToPeer(MyAttackers.get(i),message);
         }
     }

     static public void sendToDefenders(String message) throws Exception
     {
         System.out.println("Sending to defenders: "+message);
         for(int i=0;i<MyDefenders.size();i++)
         {
             if(!MyDefenders.get(i).equals(TCPClient.name));
             SendSocketsList.sendToPeer(MyDefenders.get(i),message);
         }
     }

     static public void pushAttackersList(String userName) throws Exception
     {
         String attackersList = "#:populateAttackers:";
         for(int i=0;i<MyAttackers.size();i++)
             attackersList += MyAttackers.get(i)+",";
         attackersList = attackersList.substring(0,attackersList.length()-1); //remove last comma
         attackersList += ":";
         
         SendSocketsList.sendToPeer(userName,attackersList);
     }

     static public void pushDefendersList(String userName) throws Exception
     {
         String defendersList = "#:populateDefenders:";
         for(int i=0;i<MyDefenders.size();i++)
             defendersList += MyDefenders.get(i)+",";
         defendersList = defendersList.substring(0,defendersList.length()-1);
         defendersList += ":";

         SendSocketsList.sendToPeer(userName,defendersList);
     }

     static public void addAttacker(String hostName,String userName, int sendToPeers) throws Exception
     {
        System.out.println("in addattacker:"+hostName+","+userName);

        if(TCPClient.name.equals(TCPClient.MyGameHostName))
            hostName = TCPClient.MyGameHostName;
        //proceed only if i am part of a game
         if(!TCPClient.MyGameHostName.equals("NULL"))
         {
             System.out.println("entered addattacker");
             if(MyParticipants.contains(userName))
             {
                 MyDefenders.remove(userName);
                 if(!MyAttackers.contains(userName))
                    MyAttackers.add(userName);

                 updateADLists();

                 if(sendToPeers==1)
                 {
                     String message = "#:addAttacker:"+hostName+":"+userName+":0:";
                     sendToParticipants(message);
                 }
             }
         }
     }


     static public void addDefender(String hostName,String userName, int sendToPeers) throws Exception
     {
         System.out.println("in adddefender:"+hostName+","+userName);

         if(TCPClient.name.equals(TCPClient.MyGameHostName))
            hostName = TCPClient.MyGameHostName;
         //proceed only if i am part of a game
         if(!TCPClient.MyGameHostName.equals("NULL"))
         {
             System.out.println("entered adddefender");
             if(MyParticipants.contains(userName))
             {
                 MyAttackers.remove(userName);
                 if(!MyDefenders.contains(userName))
                    MyDefenders.add(userName);

                 updateADLists();

                 if(sendToPeers==1)
                 {
                     String message = "#:addDefender:"+hostName+":"+userName+":0:";
                     sendToParticipants(message);
                 }
             }
         }
     }

     static public void updateADLists()
     {
         //String[] sta = new String[MyAttackers.size()];
         String[] sta = (String[])MyAttackers.toArray(new String[MyAttackers.size()]);
         //Menu.updateAttackers(sta);
         Menu.updateAttackers(sta);

         //String[] std = new String[MyDefenders.size()];
         String[] std = (String[])MyDefenders.toArray(new String[MyDefenders.size()]);
         Menu.updateDefenders(std);

     }

     static public void removeAttacker(String hostName,String userName, int sendToPeers) throws Exception
     {
        System.out.println("in removeattacker:"+hostName+","+userName);


         if(!TCPClient.MyGameHostName.equals("NULL"))
         {
             System.out.println("entered removeattacker");
             if(MyParticipants.contains(userName))
             {
                 MyAttackers.remove(userName);

                 //updateADLists();
                 if(MyAttackers.contains(TCPClient.name))
                    Game.updateOpponents(MyDefenders);
                 else
                    Game.updateOpponents(MyAttackers);

                 if(sendToPeers==1)
                 {
                     String message = "#:removeAttacker:"+hostName+":"+userName+":0:";
                     sendToParticipants(message);
                 }
             }
             System.out.println(MyAttackers);
         }

        MyParticipants.remove(userName);
     }


     static public void removeDefender(String hostName,String userName, int sendToPeers) throws Exception
     {
         System.out.println("in removedefender:"+hostName+","+userName);

         //proceed only if i am part of a game
         if(!TCPClient.MyGameHostName.equals("NULL"))
         {
             System.out.println("entered removedefender");
             if(MyParticipants.contains(userName))
             {
                 MyDefenders.remove(userName);

                 //updateADLists();
                 //Game.updateOpponents(MyDefenders);
                 if(MyAttackers.contains(TCPClient.name))
                    Game.updateOpponents(MyDefenders);
                 else
                    Game.updateOpponents(MyAttackers);

                 if(sendToPeers==1)
                 {
                     String message = "#:removeDefender:"+hostName+":"+userName+":0:";
                     sendToParticipants(message);
                 }
             }
             System.out.println(MyDefenders);
         }

         MyParticipants.remove(userName);
     }

     static public void logoutGame() throws Exception
     {
         //remove my name from all lists and update all participants
         if(MyAttackers.contains(TCPClient.name))
             removeAttacker(TCPClient.MyGameHostName,TCPClient.name,1);
         else if (MyDefenders.contains(TCPClient.name))
             removeDefender(TCPClient.MyGameHostName,TCPClient.name,1);

         System.exit(0);

         //remove from participant list
     }

     static public String getMyName()
     {
         return TCPClient.name;
     }

     static public String getMyTeam()
     {
         if(MyAttackers.contains(TCPClient.name))
             return "Attacker";
         else
             return "Defender";
     }
     
     static public void startGameSession(String userName) throws Exception
     {
         System.out.println("in Startgamesession");
         if((hoststable.containsKey(userName))&&(MyParticipants.contains(userName))&&(MyAttackers.size()>0)&&(MyDefenders.size()>0))
         {
             ServerConnect.sendToServer("start "+userName);
             sendToParticipants("#:startGameSession:");
             System.out.println("entered Startgamesession");
             Player.setToken(ServerConnect.fbToken);
             System.out.println("send token to player");
             Menu.startGame();
             sendOpponentsList(userName);
         }
     }

     static public void sendOpponentsList(String userName)
     {
         if(MyAttackers.contains(userName))
             Game.updateOpponents(MyDefenders);
         else
             Game.updateOpponents(MyAttackers);
     }

     static public void attackWithWord(String word) throws Exception
     {
         if(MyDefenders.contains(TCPClient.name))
             sendToAttackers("#:attackWithWord:"+TCPClient.name+":"+word+":");
         else
             sendToDefenders("#:attackWithWord:"+TCPClient.name+":"+word+":");

         System.out.println("Attacked from UserRole:"+word);
     }

     static public void interceptedWord(int position,String wordSource,int points) throws Exception
     {
         System.out.println("in interceptedword");
         if(MyDefenders.contains(TCPClient.name))
             sendToDefenders("#:interceptedWord:"+position+":"+wordSource);
         else
             sendToAttackers("#:interceptedWord:"+position+":"+wordSource);

         myScore += points;

         //if i am host
         if(TCPClient.name.equals(TCPClient.MyGameHostName))
         {
             usersScore.put(TCPClient.name,myScore);
             if(MyDefenders.contains(TCPClient.name))
             {
                 defendersScoreHash.put(TCPClient.name,myScore);
                 defendersScore += points;
                 teamScore = defendersScore;
                 opponentScore = attackersScore;
             }
             else
             {
                 attackersScoreHash.put(TCPClient.name,myScore);
                 attackersScore += points;
                 teamScore = attackersScore;
                 opponentScore = defendersScore;
             }
             
             Game.updateScore(myScore,teamScore,opponentScore);
             checkMileStoneReached();
             //sendScoreToAllAttackers();
             //sendScoreToAllDefenders();
         }

         else
            SendSocketsList.sendToPeer(TCPClient.MyGameHostName,"#:updateHostScore:"+TCPClient.name+":"+myScore+":"+points+":");

     }

     //called only if this user is HOST. upate all scores.
     static public void updateHostScores(String clientName,int clientScore,int points) throws Exception
     {
         System.out.println("in updateHostScores:"+clientName);

         if(hoststable.containsKey(TCPClient.name)) //check if host
         {
             usersScore.put(clientName, clientScore);
             if(MyDefenders.contains(clientName))
             {
                 defendersScoreHash.put(clientName, clientScore);
                 defendersScore += points; //let peer know the updated scores
                 SendSocketsList.sendToPeer(clientName,"#:updatePeerScore:"+clientScore+":"+defendersScore+":"+attackersScore+":");
                 //sendScoreToAllAttackers();
                 //sendScoreToAllDefenders();
             }
             else
             {
                 attackersScoreHash.put(clientName, clientScore);
                 attackersScore += points;
                 SendSocketsList.sendToPeer(clientName,"#:updatePeerScore:"+clientScore+":"+attackersScore+":"+defendersScore+":");
                 //sendScoreToAllAttackers();
                 //sendScoreToAllDefenders();
             }
         }
     }

     static public void updatePeerScores(int mine,int team,int opponent) throws Exception
     {
         myScore = mine;
         teamScore = team;
         opponentScore = opponent;

         Game.updateScore(myScore,teamScore,opponentScore);
         checkMileStoneReached();
     }

     static public void sendScoreToAllAttackers() throws Exception
     {
         int thisScore;

         for(int i=0;i<MyAttackers.size();i++)
         {
             if(!MyAttackers.get(i).equals(TCPClient.name))
             {
                  thisScore = attackersScoreHash.get(MyAttackers.get(i));
                  SendSocketsList.sendToPeer(MyAttackers.get(i),"#:updatePeerScore:"+thisScore+":"+attackersScore+":"+defendersScore+":");
             }
         }

     }

     static public void sendScoreToAllDefenders() throws Exception
     {
         int thisScore;

         for(int i=0;i<MyDefenders.size();i++)
         {
             if(!MyDefenders.get(i).equals(TCPClient.name))
             {
                  thisScore = defendersScoreHash.get(MyDefenders.get(i));
                  SendSocketsList.sendToPeer(MyAttackers.get(i),"#:updatePeerScore:"+thisScore+":"+defendersScore+":"+attackersScore+":");
             }
         }
     }

     static public void checkMileStoneReached() throws Exception
     {
         if((teamScore > winningScore)&&(milestonereached==0))
         {
             System.out.println("Attackers Milestone Reached:"+teamScore+","+winningScore);
             milestonereached = 1;

             //handle my menu
             if(MyAttackers.contains(TCPClient.name))
             {
                 gameWinLose("win");
                 sendToAttackers("#:gameWinLose:win:");
                 sendToDefenders("#:gameWinLose:lose:");
             }
             else
             {
                 gameWinLose("win");
                 sendToAttackers("#:gameWinLose:lose:");
                 sendToDefenders("#:gameWinLose:win:");
             }
         }
         else if((opponentScore > winningScore)&&(milestonereached==0))
         {
             System.out.println("Defenders Milestone Reached:"+defendersScore+","+winningScore);
             milestonereached = 1;
             
             if(MyAttackers.contains(TCPClient.name))
             {
                 gameWinLose("lose");
                 sendToAttackers("#:gameWinLose:lose:");
                 sendToDefenders("#:gameWinLose:win:");
             }
             else
             {
                 gameWinLose("lose");
                 sendToAttackers("#:gameWinLose:win:");
                 sendToDefenders("#:gameWinLose:lose:");
             }
         }
         
     }

     static public void gameWinLose(String status)
     {
         Menu.endGame(status,attackersScoreHash,defendersScoreHash);
     }

     static public void wordMissed(String opponentName) throws Exception
     {
         int points = 5;
         System.out.println("in WordMissed:"+opponentName);

         if(TCPClient.name.equals(TCPClient.MyGameHostName)) //i am host?
         {
             updateHostScoreOpponent(opponentName,points);
         }
         else

            SendSocketsList.sendToPeer(TCPClient.MyGameHostName,"#:updateHostScoreOpponent:"+opponentName+":"+points+":");
     }

     static public void updateHostScoreOpponent(String opponentName,int points) throws Exception
     {
         if(hoststable.containsKey(TCPClient.name)) //check if host
         {
             int newScore = points;
             if(usersScore.containsKey(opponentName))
                 newScore += (Integer)usersScore.get(opponentName);

             usersScore.put(opponentName,newScore);

             if(MyDefenders.contains(opponentName))
             {
                 defendersScoreHash.put(opponentName,newScore);
                 defendersScore += points; //let peer know the updated scores
                 if(opponentName.equals(TCPClient.name))
                 {
                     updatePeerScores(newScore,defendersScore,attackersScore);
                 }
                 else
                    SendSocketsList.sendToPeer(opponentName,"#:updatePeerScore:"+newScore+":"+defendersScore+":"+attackersScore+":");
             }
             else
             {
                 attackersScoreHash.put(opponentName,newScore);
                 attackersScore += points;
                 if(opponentName.equals(TCPClient.name))
                 {
                     updatePeerScores(newScore,attackersScore,defendersScore);
                 }
                 else
                    SendSocketsList.sendToPeer(opponentName,"#:updatePeerScore:"+newScore+":"+attackersScore+":"+defendersScore+":");
             }
         }
     }

     static public void chatWithTeam(String message) throws Exception
     {
         if(MyAttackers.contains(TCPClient.name))
             sendToAttackers("#:teamChat:"+TCPClient.name+":"+message+":");
         else
             sendToDefenders("#:teamChat:"+TCPClient.name+":"+message+":");
     }

     static public void chatWithParticipants(String message) throws Exception
     {
         sendToParticipants("#:globalChat:"+TCPClient.name+":"+message+":");
     }

     static public void showTeamChat(String sender,String message)
     {
         Game.displayTeamChat(sender,message);
     }

     static public void showGlobalChat(String sender,String message)
     {
         Game.displayGlobalChat(sender,message);
     }

     static public void lifeZero()
     {
         //call vinoth's function
         Menu.endGame("lose",attackersScoreHash,defendersScoreHash);
     }

     static public void updateFileName(String name)
     {
         fileName = name;
     }

     static public void sendFile() throws IOException,InterruptedException,Exception
     {
         if (TCPClient.name.equals(TCPClient.MyGameHostName))
         {
             //String filename = "ERap.mp3";
             File myFile = new File(fileName);
             //File myFile = new File(fileName);
             byte[] mybytearray = new byte[(int) myFile.length()];
             FileInputStream fis = new FileInputStream(myFile);
             BufferedInputStream bis = new BufferedInputStream(fis);
             bis.read(mybytearray, 0, mybytearray.length);

             for (int i=0; i<MyParticipants.size(); i++)
             {
                 if (!MyParticipants.get(i).equals(TCPClient.name))
                 {
                     String peername = MyParticipants.get(i);
                     SendSocketsList.sendFileToPeer(peername, mybytearray, fileName);
                 }
             }
         }
     }

}
